
local japi = require 'jass.japi'
local hook = require 'jass.hook'
local code = require 'jass.code'
local util = require 'util.color'

local function spectrum_parse(str)
    local spectrum = { }
    local spectrumCount = 0
    for color_str in str:gmatch("[^;]+") do 
        if #color_str == 10 then
            local color_num = tonumber(color_str:match("|c([%w]+)"), 16)
            if not color_num then 
                color_num = 0xFFFFFFFF
            end
            spectrumCount = spectrumCount + 1
            spectrum[#spectrum+1] = color_num
        else
            local color_num = 0xFFFFFFFF
            spectrumCount = spectrumCount + 1
            spectrum[#spectrum+1] = color_num
        end
    end
    if spectrumCount == 0 then 
        spectrumCount = 1 
        spectrum[1] = 0xFFFFFFFF
    end 
    spectrum[0] = spectrum[spectrumCount]
    spectrum[-1] = spectrum[spectrumCount-1]
    return spectrum
end

local painter_class = { 

    color = function(self, config)
        self.spectrum = spectrum_parse(config)
        self.tween = ac.tween("线性", self.delay)
        self.tween:begin({T = 1}):after({T = #self.spectrum+1})
        return self 
    end,

    content = function(self, text)
        self.words = ac.splittext(text, true)
        return self 
    end,

    node =  function(self, clock)
        local tween = self.tween
        local words = self.words
        local spectrum = self.spectrum
        local spectrumCount = #spectrum
        local woldsCount = #words
        tween:set(math.max(0, clock % self.delay))
        local subject = tween.subject
        local T = subject.T
        local result = { }
        for i = 1, woldsCount do 
            local r = T - ((1 / woldsCount) * (i-1))
            local n, f = math.modf(r)
            local source = spectrum[n-1]
            local target = spectrum[n]
            local color = util.lerp(source, target, f)
            result[#result+1] = ("|c%08X%s|r"):format(color, words[i])
        end
        return table.concat(result)
    end,

    remove = function(self)
        if self.removed then 
            return 
        end 
        self.removed = true 
        self.tween = nil 
    end,
}

painter_class.__index = painter_class

-- 创建
function ac.painter(text, delay, config)
    local painter = setmetatable({
        delay = delay,
        words = ac.splittext(text, true),
        tween = ac.tween("线性", delay),
        spectrum = spectrum_parse(config),
    }, painter_class)
    painter.tween:begin({T = 1}):after({T = #painter.spectrum+1})
    return painter
end 

return painter_class